#include "myheadd.h"


// 全局变量定义
Friend *friend_list;
pthread_mutex_t list_mutex = PTHREAD_MUTEX_INITIALIZER;
unsigned short my_private_port = 0;
unsigned short my_file_port = 0;




int main(void) 
{

   
    pthread_t t1, t2, t3,t4;
    int n;
    int flag = 1;
    char user_name[20] = {0};

    // 初始化好友链表
    friend_list = init_list();
    if (!friend_list) 
    {
        perror("链表初始化失败");
        return EXIT_FAILURE;
    }

    // 输入用户名
    printf("请输入用户名：");
    if (scanf("%19s", user_name) != 1) // 限制长度，防止溢出
    { 
        printf("输入错误\n");
        return EXIT_FAILURE;
    }
    while (getchar() != '\n'); // 清空输入缓冲区
    
     /////共享文件夹
    shared_start_service(user_name);//启动共享文件夹
    ////共享文件夹
    

    my_private_port = 54320 + (getpid() % 1000);// 生成唯一私聊端口（优化端口分配逻辑）
    int temp_sock = socket(AF_INET, SOCK_DGRAM, 0);
    struct sockaddr_in temp_addr;
    temp_addr.sin_family = AF_INET;
    temp_addr.sin_port = htons(my_private_port);
    temp_addr.sin_addr.s_addr =htonl(INADDR_ANY);
    if (bind(temp_sock, (struct sockaddr *)&temp_addr, sizeof(temp_addr)) < 0) 
    {
        printf("端口 %d 被占用，自动切换到 %d\n", my_private_port, my_private_port + 1);
        my_private_port++;
    }
    close(temp_sock);

    my_file_port = 56780 + (getpid() % 1000);
    int file_temp_sock = socket(AF_INET, SOCK_STREAM, 0);  // 生成唯一文件传输端口（优化端口分配逻辑）
    struct sockaddr_in file_temp_addr;                     // 用新变量名
    file_temp_addr.sin_family = AF_INET;
    file_temp_addr.sin_port = htons(my_file_port);
    file_temp_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind(file_temp_sock, (struct sockaddr *)&file_temp_addr, sizeof(file_temp_addr)) < 0) 
    {
        printf("文件传输端口 %d 被占用，自动切换到 %d\n", my_file_port, my_file_port + 1);
        my_file_port++;
    }
    close(file_temp_sock);  // 用完关闭

  


    if (pthread_create(&t1, NULL, send_broadcast, user_name) != 0) // 创建线程（带错误检查）
    {
        perror("创建广播发送线程失败");
        return EXIT_FAILURE;
    }
    if (pthread_create(&t2, NULL, recv_broadcast, user_name) != 0)
    {
        perror("创建广播接收线程失败");
        pthread_cancel(t1);
        return EXIT_FAILURE;
    }
    if (pthread_create(&t3, NULL, private_chat_listener, user_name) != 0) 
    {
        perror("创建私聊监听线程失败");
        pthread_cancel(t1);
        pthread_cancel(t2);
        
        return EXIT_FAILURE;//表示程序以失败状态退出。
    }
    if (pthread_create(&t4, NULL, file_transfer_listener, user_name) != 0) 
    {
        perror("创建文件传输监听线程失败");
        pthread_cancel(t1);
        pthread_cancel(t2);
        pthread_cancel(t3);   // 取消已有线程并退出
        return EXIT_FAILURE;
    }

    // 主菜单不循环
    printf("\n=================== 功能菜单 =======================\n");
    printf("=====按0选择下线=========   ====按1显示好友在线列表=====\n");
    printf("===按2进行1对1私聊=======   ====按3进行好友群聊=========\n");
    printf("===按4进行1对1传输文件===   =====按5进入共享文件夹=======\n");
    printf("===按6查询聊天记录=======   =====按7修改资料=============\n");
    printf("======================================================\n");
 
    while (flag) 
    {
        printf("======请输入操作码(0~7)||确认码(8~9)--->:");
        if (scanf("%d", &n) != 1) 
        {
            printf("输入错误，请重新输入\n");
            while (getchar() != '\n'); // 清空错误输入
            continue;
        }
        while (getchar() != '\n'); // 清空缓冲区

        switch(n) 
        {
            case 0:
                pthread_cancel(t1);
                pthread_cancel(t2);
                pthread_cancel(t3);
                pthread_cancel(t4);
                flag = 0;
                send_offline_msg(user_name); // 发送下线通知
                sleep(1); // 等待通知发送完成
                // 取消所有线程
               
                break;
            case 1:
                // 显示在线列表
                printf("\n----- 好友在线列表 -----\n");
                show_friend_list();
                printf("-----------------------\n");
                break;
            case 2:
                // 发起私聊
                printf("请输入好友用户名: ");
                char friend_name[20];
                if (scanf("%19s", friend_name) != 1) 
                {
                    printf("输入错误\n");
                    while (getchar() != '\n');
                    break;
                }
                while (getchar() != '\n');
                start_private_chat(friend_name, user_name);
                break;
            case 3:
                printf("<请输入---<组播IP><端口>--->\n");
                printf("示例:224.0.0.11  58888\n");
                char uip[20];
                int uport;
                if (scanf("%19s", uip) != 1) 
                {
                    printf("组播ip输入错误\n");
                    while (getchar() != '\n');
                    break;
                }
                while (getchar() != '\n');
                printf("组播ip:%s--->下方输入端口号👇\n",uip);
                scanf("%d", &uport); 
                while (getchar() != '\n');
                printf("端口:%d\n",uport);
                ccc(uip,uport,user_name);
                break;
            case 4:
                printf("\n-----即将开始传输文件-----\n");
                printf("请输入想要传输文件的好友用户名: ");
                char f_friend[20];
                if (scanf("%19s", f_friend) != 1) 
                {
                    printf("输入好友名字有误\n");
                    while (getchar() != '\n');
                    break;
                }
                while (getchar() != '\n');

                printf("请输入文件路径: ");
                char filepath[100];
                if (scanf("%99s", filepath) != 1) 
                {
                    printf("文件路径输入有误\n");
                    while (getchar() != '\n');
                    break;
                }
                while (getchar() != '\n');

                start_file_transfer(f_friend, filepath); // 调用传输函数
                printf("-----------------------\n");
                break;
             case 5:
                printf("\n===== 共享文件夹 =====");
                printf("\n1. 查看本地共享文件");
                printf("\n2. 查看好友共享文件");
                printf("\n3. 下载好友共享文件");
                printf("\n请选择: ");
                int choice;
                scanf("%d", &choice);
                while (getchar() != '\n'); // 清空缓冲区

                if (choice == 1) 
                {
                    shared_list_local(user_name);//查看本地共享文件
                } 
                else if (choice == 2) 
                {
                    char friend_name[20];
                    printf("输入好友用户名: ");
                    fgets(friend_name, sizeof(friend_name), stdin);
                    friend_name[strcspn(friend_name, "\n")] = '\0';
                    shared_get_friend_list(friend_name);//获取好友共享文件
                } 
                else if (choice == 3) 
                {
                    char friend_name[20], filename[100];
                    printf("输入好友用户名: ");
                    fgets(friend_name, sizeof(friend_name), stdin);
                    friend_name[strcspn(friend_name, "\n")] = '\0';

                    printf("输入要下载的文件名: ");
                    fgets(filename, sizeof(filename), stdin);
                    filename[strcspn(filename, "\n")] = '\0';

                    shared_download_file(friend_name, filename,user_name);//下载共享文件
                }
                break;
             case 6:
                printf("请选择查询类型（1-私聊 2-群聊）: ");
                int type;
                scanf("%d", &type);
                while (getchar() != '\n');
                
                if (type == 1) 
                {
                    char f_name[20];
                    printf("请输入好友用户名: ");
                    scanf("%19s", f_name);
                    while (getchar() != '\n');
                    read_history(PRIVATE_CHAT, user_name, f_name);
                } 
                else if (type == 2) 
                {
                    char group_ip[20];
                    int  group_port;
                    printf("请输入群聊IP: ");
                    scanf("%19s", group_ip);
                    while (getchar() != '\n');
                    printf("请输入群聊端口: ");
                    scanf("%d",&group_port);
                    while (getchar() != '\n');
                    char group_id[30];
                    snprintf(group_id, 30, "%s:%d", group_ip, group_port);
                    read_history(GROUP_CHAT, user_name, group_id);
                }
                break;
             case 7:
                printf("\n----- 个性签名修改与查看 ------\n");
                aaa(user_name);
                printf("-------------------------------\n");
                break;
            default:
                
               continue;
            }
        }

    // 等待线程结束并清理资源
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    pthread_join(t3, NULL);
    pthread_join(t4, NULL);
    pthread_mutex_destroy(&list_mutex);
    printf("===========程序已退出============\n");
    return EXIT_SUCCESS;
}

